#include "preHeader.h"
#include "GateServerSession.h"
#include "GateServerSessionHandler.h"
#include "GateServerMgr.h"
#include "SocialServer.h"
#include "C2GuildPacketHandler.h"
#include "S2GuildPacketHandler.h"
#include "Guild/GuildMgr.h"
#include "C2RankPacketHandler.h"
#include "S2RankPacketHandler.h"
#include "Rank/RankMgr.h"
#include "C2OperatingPacketHandler.h"
#include "S2OperatingPacketHandler.h"
#include "Operating/OperatingActivityMgr.h"
#include "Game/TransMgr.h"

GateServerSession::GateServerSession(uint32 sn)
: Session("GateServerSession")
, m_sn(sn)
, m_gsGateSN(0)
{
}

GateServerSession::~GateServerSession()
{
}

int GateServerSession::HandlePacket(INetPacket *pck)
{
	if (IsReady() || pck->GetOpcode() < FLAG_GATE2SOCIAL_MSG_NEED_REGISTER_BEGIN) {
		return sGateServerSessionHandler.HandlePacket(this, *pck);
	} else {
		return SessionHandleUnhandle;
	}
}

void GateServerSession::OnShutdownSession()
{
	sTransMgr.RemoveGateServer(this);
	sGateServerMgr.RemoveGateServer(this);
	WLOG("Close GateServerSession [sn:%u gsGateSN:%u].", m_sn, m_gsGateSN);
	Session::OnShutdownSession();
}

void GateServerSession::OnRecvPacket(INetPacket *pck)
{
	switch (pck->GetOpcode()) {
	case CGT_TRANS_SERVER_PACKET:
		TransServerPacket(pck);
		break;
	case CGT_TRANS_CLIENT_PACKET:
		TransClientPacket(pck);
		break;
	default:
		Session::OnRecvPacket(pck);
		break;
	}
}

void GateServerSession::TransServerPacket(INetPacket *pck) const
{
	pck->UnpackPacket();
	auto opcode = pck->GetOpcode();
	if (sS2GuildPacketHandler.CanHandle(opcode)) {
		sGuildMgr.PushRecvPacket(IServerService::NewServerPacket(pck));
		return;
	}
	if (sS2RankPacketHandler.CanHandle(opcode)) {
		sRankMgr.PushRecvPacket(IServerService::NewServerPacket(pck));
		return;
	}
	if (sS2OperatingPacketHandler.CanHandle(opcode)) {
		sOperatingActivityMgr.PushRecvPacket(IServerService::NewServerPacket(pck));
		return;
	}
	WLOG("Trans server packet[%u] failed, can't find recipient.", opcode);
	delete pck;
}

void GateServerSession::TransClientPacket(INetPacket *pck) const
{
	uint32 uid;
	*pck >> uid;
	pck->UnpackPacket();
	auto opcode = pck->GetOpcode();
	if (sC2GuildPacketHandler.CanHandle(opcode)) {
		sGuildMgr.PushRecvPacket(IServerService::NewClientPacket(uid, pck));
		return;
	}
	if (sC2RankPacketHandler.CanHandle(opcode)) {
		sRankMgr.PushRecvPacket(IServerService::NewClientPacket(uid, pck));
		return;
	}
	if (sC2OperatingPacketHandler.CanHandle(opcode)) {
		sOperatingActivityMgr.PushRecvPacket(IServerService::NewClientPacket(uid, pck));
		return;
	}
	WLOG("Trans client packet[%u] failed, can't find recipient.", opcode);
	delete pck;
}

int GateServerSessionHandler::HandleRegister(GateServerSession *pSession, INetPacket &pck)
{
	sGateServerMgr.AddGateServer(pSession);

	pck >> pSession->m_gsGateSN;
	sTransMgr.AddGateServer(pSession);

	bool flagHandlers[GAME_OPCODE::CSMSG_COUNT];
	sC2GuildPacketHandler.InitHandlerFlags(flagHandlers, ARRAY_SIZE(flagHandlers));
	sC2RankPacketHandler.MergeHandlerFlags(flagHandlers, ARRAY_SIZE(flagHandlers));

	NetPacket resp(SGT_REGISTER_RESP);
	resp.Append(flagHandlers, sizeof(flagHandlers));
	pSession->PushSendPacket(resp);

	NLOG("GateServer Register Success As [sn:%u gsGateSN:%u].",
		pSession->m_sn, pSession->m_gsGateSN);

	return SessionHandleSuccess;
}

int GateServerSessionHandler::HandleUpdateGsGateSn(GateServerSession *pSession, INetPacket &pck)
{
	auto oldGsGateSN = pSession->m_gsGateSN;
	pck >> pSession->m_gsGateSN;
	sTransMgr.UpdateGateServerGSSN(oldGsGateSN, pSession);
	return SessionHandleSuccess;
}
